#include <iostream>

#include <workflow/WFFacilities.h>
#include <workflow/MySQLResult.h>
#include <wfrest/HttpServer.h>

#include <nlohmann/json.hpp>


using namespace std;
using namespace wfrest;
using Json = nlohmann::json;

static WFFacilities::WaitGroup waitGroup(1);

void test0()
{
    HttpServer server;

    server.GET("/hello", [](const HttpReq * , HttpResp * resp){
        //resp->append_output_body("method is GET, path is /hello");
        //给响应体中添加字符串
        resp->String("method is GET, path is /hello");
    });

    //重定向
    server.GET("/redirect", [](const HttpReq * , HttpResp * resp){
        resp->set_status_code("302");
        //resp->add_header_pair("Location", "/hello");
        //设置首部字段时，可以直接使用map来操作
        resp->headers["Location"] = "/hello";
    });

    //直接获取url中的查询词
    server.GET("/query_list", [](const HttpReq * req, HttpResp * ){
        auto & queryKV = req->query_list();
        for(auto & elem : queryKV) {
            //cout << elem.first << " -> " << elem.second << endl;
        }

        //cout << "username:" << req->query("username") << endl;
    });

    //部署静态资源
    server.GET("/login", [](const HttpReq * , HttpResp * resp){
        resp->File("/usr/local/nginx/html/postform.html");
    });

    server.POST("/login", [](const HttpReq * req, HttpResp * ){
        if(req->content_type() == wfrest::APPLICATION_URLENCODED) {
            auto & formKV = req->form_kv();
            cout << "username:" << formKV["username"] << endl
                 << "password:" << formKV["password"] << endl;
        }
    });

    server.GET("/formdata", [](const HttpReq *, HttpResp * resp){
        resp->File("index.html");
    });

    server.POST("/formdata", [](const HttpReq * req, HttpResp *){
        if(req->content_type() == wfrest::MULTIPART_FORM_DATA)  {
            auto & form = req->form();
            for(auto & elem : form) {
                printf("first: %s, second.first: %s, second.second: %s\n"
                       , elem.first.c_str()
                       , elem.second.first.c_str()
                       , elem.second.second.c_str());
            }
        }
    });

    //使用序列，添加一个参数即可
    server.GET("/series", [](const HttpReq* , HttpResp* resp, SeriesWork * series){
        auto timerTask = WFTaskFactory::create_timer_task(3 * 1000 * 1000, 
        [resp](WFTimerTask * timertask){
            resp->String("series test is done");                                                     
        });
        series->push_back(timerTask);
    });

    //访问MySQL的用法
    server.GET("/mysqltest0", [](const HttpReq *, HttpResp * resp){
        //返回给客户端的是一个JSON对象
        resp->MySQL("mysql://root:1234@localhost", "select * from cloudisk.tbl_user_token");
    });

    server.GET("/mysqltest1", [](const HttpReq *, HttpResp * resp){
        resp->MySQL("mysql://root:1234@localhost", "select * from cloudisk.tbl_user_token", 
            [resp](Json * json){
                string cell = (*json)["result_set"][0]["rows"][0][1];
                resp->String(cell);
            });
        });

    using namespace protocol;
    server.GET("/mysqltest2", [](const HttpReq *, HttpResp * resp){
        resp->MySQL("mysql://root:1234@localhost", "select * from cloudisk.tbl_user_token", 
        [resp](MySQLResultCursor* cursor){
            vector<vector<MySQLCell>> rows;
            cursor->fetch_all(rows);
            string cell = rows[0][2].as_string();
            resp->String(cell);
        });
    });

    server.GET("/mysqltest3", [](const HttpReq* , HttpResp* resp, SeriesWork * series){
        string mysqlurl = "mysql://root:1234@localhost";
        auto mysqlTask = WFTaskFactory::create_mysql_task(mysqlurl, 0,  
        [resp](WFMySQLTask* mysqltask){
            auto mysqlresp = mysqltask->get_resp();
            MySQLResultCursor cursor(mysqlresp);
            vector<vector<MySQLCell>> rows;
            cursor.fetch_all(rows);
            string cell = rows[0][2].as_string();
            resp->String(cell);
        });
        auto req = mysqlTask->get_req();
        string query("select * from cloudisk.tbl_user_token");
        req->set_query(query);
        series->push_back(mysqlTask);
    });

    //在wfrest中访问Redis
    server.GET("/redistest0", [](const HttpReq *, HttpResp * resp){
        string redisurl("redis://localhost");
        resp->Redis(redisurl, "SET", {"48wfrest", "yes"});
    });

    server.GET("/redistest1", [](const HttpReq *, HttpResp * resp){
        string redisurl("redis://localhost");
        resp->Redis(redisurl, "GET", {"48wfrest"}, [resp](Json * json){
            string ret = (*json)["status"];
            resp->String(ret);
            //resp->String("hello,redis");
        });
    });

    if(server.track().start(8888) == 0) {
        server.list_routes();
        waitGroup.wait();
        server.stop();
    } else {
        printf("server cannnot start\n");
    }
}


int main()
{
    test0();
    return 0;
}

